home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
051-060
/
amok56
/
m2maker
/
txt
/
xcopy.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
13KB
|
422 lines
(*---------------------------------------------------------------------------
:Program. M2Maker
:Author. Thomas Stolze
:Address. Goslarsche Str. 32, W-3000 Hannover 21, Germany
:Phone. (0)511 / 75 10 77
:Version. V2.3
:Date. 09-Feb-91
:Copyright. Shareware
:Language. Modula-2
:Translator. M2Amiga V4.0d
:LastUpdate. 05-JUN-91
:Contents. Programming Utility.
:Remark. Supports the M2Amiga System (C) by A+L AG Switzerland
---------------------------------------------------------------------------*)
IMPLEMENTATION MODULE XCopy;
IMPORT FileSystem;
FROM Arts IMPORT BreakPoint,Terminate;
FROM DosD IMPORT accessRead,Date,
FileInfoBlock,FileInfoBlockPtr,
FileLockPtr,noFreeStore,objectNotFound,ok,
setDate,StandardPacketPtr;
FROM DosL IMPORT CreateDir,CurrentDir,DeviceProc,
DupLock,Examine,ExNext,Lock,UnLock;
FROM ExecD IMPORT message,MsgPortPtr;
FROM ExecL IMPORT CopyMem,GetMsg,PutMsg,WaitPort;
FROM ExecSupport IMPORT CreatePort,DeletePort;
FROM Heap IMPORT Allocate,Deallocate;
FROM InitIntuition IMPORT PrintStatus;
FROM String IMPORT CapString,Compare,Concat,Copy,Length;
FROM Storage IMPORT ALLOCATE,Available,DEALLOCATE;
FROM SYSTEM IMPORT ADDRESS,ADR,BPTR,CAST;
(*FROM InOut IMPORT WriteInt,WriteLn,WriteString;*)
CONST bufferSize = 20480;
VAR Buffer : ADDRESS;
cIPtr : FileInfoBlockPtr;
PROCEDURE AllocEntry(VAR entryPtr: ADDRESS; size : CARDINAL): BOOLEAN;
BEGIN
IF Available(size) THEN ALLOCATE(entryPtr,size); RETURN TRUE END;
RETURN FALSE;
END AllocEntry;
PROCEDURE DeallocEntry(VAR entryPtr : ADDRESS; size : CARDINAL);
BEGIN
DEALLOCATE(entryPtr,size); entryPtr:=NIL;
END DeallocEntry;
PROCEDURE MakeStandardPacket(ReplyPort : MsgPortPtr;
Type,
Arg1,Arg2,
Arg3,Arg4 : LONGINT): StandardPacketPtr;
VAR PacketPtr : StandardPacketPtr;
BEGIN
IF AllocEntry(PacketPtr,SIZE(PacketPtr^)) THEN
IF PacketPtr # NIL THEN
WITH PacketPtr^ DO
pkt.link := ADR(msg); (* init "DosPacket" *)
pkt.port := ReplyPort;
pkt.type := Type;
pkt.res1 := 0;
pkt.res2 := 0;
pkt.arg1 := Arg1;
pkt.arg2 := Arg2;
pkt.arg3 := Arg3;
pkt.arg4 := Arg4;
pkt.arg5 := 0;
pkt.arg6 := 0;
pkt.arg7 := 0;
msg.node.name := ADR(pkt); (* init "Message" *)
msg.node.succ := NIL;
msg.node.pred := NIL;
msg.node.type := message;
msg.node.pri := 0;
msg.replyPort := ReplyPort;
msg.length := SIZE(msg)
END
END;
RETURN PacketPtr;
END;
RETURN NIL;
END MakeStandardPacket;
PROCEDURE FreeStandardPacket(VAR PacketPtr : StandardPacketPtr );
BEGIN
IF PacketPtr # NIL THEN
DeallocEntry(PacketPtr,SIZE(PacketPtr^)); PacketPtr:=NIL
END
END FreeStandardPacket;
PROCEDURE SendPacket(HandlerPort : MsgPortPtr;
Type,
Arg1,Arg2,
Arg3,Arg4 : LONGINT;
VAR Result : LONGINT): LONGINT;
VAR PacketPtr : StandardPacketPtr;
myPort : MsgPortPtr;
BEGIN
IF HandlerPort = NIL THEN RETURN objectNotFound END;
myPort:= CreatePort(NIL,0);
IF myPort = NIL THEN RETURN noFreeStore END;
PacketPtr:=MakeStandardPacket(myPort,Type,Arg1,Arg2,Arg3,Arg4);
IF PacketPtr = NIL THEN DeletePort(myPort); RETURN noFreeStore END;
PutMsg(HandlerPort,PacketPtr);
REPEAT
WaitPort(myPort)
UNTIL GetMsg(myPort) = PacketPtr;
WITH PacketPtr^.pkt DO
Result:=res1; Type:=res2
END;
DeletePort(myPort); FreeStandardPacket(PacketPtr);
IF Result = 0 THEN RETURN Type ELSE RETURN ok END;
END SendPacket;
PROCEDURE MakeBSTR(Text : ARRAY OF CHAR): BPTR;
VAR p : POINTER TO ARRAY [0..1] OF SHORTCARD;
l : INTEGER;
BStrPtr : BPTR;
BEGIN
l:=INTEGER(Length(Text));
Allocate(p,l+2);
BStrPtr:=BPTR(ADDRESS(p));
IF p # NIL THEN
p^[0]:=SHORTCARD(l); INC(p); CopyMem(ADR(Text[0]),p,l); INC(p,l); p^[0]:=0;
END;
RETURN BStrPtr
END MakeBSTR;
PROCEDURE FreeBSTR(VAR BStrPtr: BPTR );
VAR p : ADDRESS;
BEGIN
IF BStrPtr # NIL THEN
p:=ADDRESS(BStrPtr); Deallocate(p); BStrPtr:=NIL
END
END FreeBSTR;
PROCEDURE SetOneDate(name : ARRAY OF CHAR;
date : Date;
currentLock : LONGINT): BOOLEAN;
VAR Response,r : LONGINT;
FName : BPTR;
FDate : ADDRESS;
DevicePort : MsgPortPtr;
BEGIN
FName:=MakeBSTR(name);
IF FName = NIL THEN
RETURN FALSE;
ELSE
FDate:=ADR(date);
DevicePort:=DeviceProc(ADR(name));
IF DevicePort = NIL THEN
FreeBSTR(FName); RETURN FALSE;
ELSE
IF currentLock = 0 THEN
FreeBSTR(FName); RETURN FALSE;
ELSE
Response:=SendPacket(DevicePort,setDate,0,
currentLock,CAST(LONGINT,FName),FDate,r);
END
END;
FreeBSTR(FName);
END;
RETURN (Response = 0);
END SetOneDate;
PROCEDURE MakePath(dir,file : ARRAY OF CHAR; VAR path : ARRAY OF CHAR);
VAR i : INTEGER;
BEGIN
i:=Length(dir); Copy(path,dir);
IF i > 0 THEN
IF (path[i-1] # ":") AND (path[i-1] # "/") THEN Concat(path,"/") END;
END;
Concat(path,file);
END MakePath;
PROCEDURE FilterLastDir(str : ARRAY OF CHAR; VAR dir : ARRAY OF CHAR);
VAR i,j,k : INTEGER;
BEGIN
i:=Length(str); j:=0; k:=0;
REPEAT DEC(i) UNTIL ((i < 0) OR (str[i] = ":")) OR (str[i] = "/");
FOR k:=i+1 TO Length(str) DO dir[j]:=str[k]; INC(j); END;
MakePath(dir,"",dir);
END FilterLastDir;
PROCEDURE GetFileDosDate(name : ARRAY OF CHAR; VAR time : Date): BOOLEAN;
VAR lock : FileLockPtr;
BEGIN
lock:=Lock(ADR(name),accessRead);
IF lock # NIL THEN
IF Examine(lock,cIPtr) THEN time:=cIPtr^.date; END;
UnLock(lock); RETURN TRUE;
END;
RETURN FALSE;
END GetFileDosDate;
PROCEDURE XCopyFile(name : ARRAY OF CHAR;
src,
dest : FileLockPtr;
fInfo : FileInfoBlockPtr;
upDate : BOOLEAN): BOOLEAN;
VAR olddestLock : FileLockPtr;
rfile,sfile : FileSystem.File;
res : BOOLEAN;
rActual,
sActual : LONGINT;
PROCEDURE CompareDates(): BOOLEAN;
VAR lock : FileLockPtr;
BEGIN
IF upDate THEN
lock:=Lock(ADR(name),accessRead);
IF lock # NIL THEN
IF Examine(lock,cIPtr) THEN
IF cIPtr^.date.days = fInfo^.date.days THEN
IF cIPtr^.date.minute = fInfo^.date.minute THEN
IF cIPtr^.date.tick = fInfo^.date.tick THEN
UnLock(lock); RETURN FALSE;
END;
END;
END;
END;
UnLock(lock);
END;
END;
RETURN TRUE;
END CompareDates;
BEGIN
FileSystem.Lookup(rfile,name,bufferSize,FALSE); res:=TRUE;
IF rfile.res = FileSystem.done THEN
olddestLock:=CurrentDir(dest);
IF CompareDates() THEN
FileSystem.Lookup(sfile,name,bufferSize,TRUE);
IF sfile.res = FileSystem.done THEN
REPEAT
FileSystem.ReadBytes(rfile,Buffer,bufferSize,rActual);
FileSystem.WriteBytes(sfile,Buffer,rActual,sActual);
UNTIL rfile.eof;
END;
FileSystem.Close(sfile);
res:=SetOneDate(name,fInfo^.date,LONGINT(dest));
END;
dest:=CurrentDir(olddestLock);
ELSE
res:=FALSE;
END;
FileSystem.Close(rfile);
RETURN res;
END XCopyFile;
PROCEDURE XCopySubDirectories(src,dest : FileLockPtr; type : XType): BOOLEAN;
VAR oldLock,
newLock,
dLock : FileLockPtr;
counter : CARDINAL;
name : ARRAY [0..31] OF CHAR;
fileInfoPtr : FileInfoBlockPtr;
PROCEDURE MakeDestDir(): BOOLEAN;
VAR oLock : FileLockPtr;
file : ARRAY [0..31] OF CHAR;
res : BOOLEAN;
BEGIN
IF (txt = type) THEN
Copy(file,name); CapString(file);
IF Compare("TXT",file) # 0 THEN RETURN FALSE END;
END;
res:=TRUE;
oLock:=CurrentDir(dest);
dLock:=CreateDir(ADR(name));
IF dLock = NIL THEN
dLock:=Lock(ADR(name),accessRead);
IF dLock = NIL THEN res:=FALSE END;
END;
dest:=CurrentDir(oLock);
RETURN res;
END MakeDestDir;
BEGIN
IF AllocEntry(fileInfoPtr,SIZE(FileInfoBlock)) THEN
counter:=0; oldLock:=CurrentDir(src);
IF Examine(src,fileInfoPtr) THEN
REPEAT
Copy(name,fileInfoPtr^.fileName);
IF counter > 0 THEN
IF fileInfoPtr^.dirEntryType > 0 THEN
IF (all = type) OR (txt = type) THEN
IF MakeDestDir() THEN;
newLock:=Lock(ADR(name),accessRead);
IF newLock # NIL THEN
IF NOT XCopySubDirectories(newLock,dLock,type) THEN
PrintStatus("Copy Error. Error ignored !");
END;
UnLock(dLock); dLock:=NIL;
UnLock(newLock); newLock:=NIL;
END;
END;
END;
ELSE
IF NOT XCopyFile(name,src,dest,fileInfoPtr,TRUE) THEN
src:=CurrentDir(oldLock); RETURN FALSE;
END;
END;
END;
INC(counter);
UNTIL (ExNext(src,fileInfoPtr) = FALSE);
src:=CurrentDir(oldLock);
END;
DeallocEntry(fileInfoPtr,SIZE(FileInfoBlock));
RETURN TRUE;
ELSE
RETURN FALSE;
END;
END XCopySubDirectories;
PROCEDURE XCopySingleFile(src,dest : ARRAY OF CHAR): BOOLEAN;
VAR name : ARRAY [0..31] OF CHAR;
srcPath,
destPath : ARRAY [0..255] OF CHAR;
srcLock,
destLock,
dLock,
olddestLock : FileLockPtr;
rfile,sfile : FileSystem.File;
res : BOOLEAN;
rActual,
sActual : LONGINT;
BEGIN
MakePath(src,"",srcPath); srcPath[Length(srcPath)-1]:=00C;
FilterLastDir(srcPath,name);
MakePath(dest,name,destPath); destPath[Length(destPath)-1]:=00C;
FileSystem.Lookup(rfile,srcPath,bufferSize,FALSE); res:=TRUE;
IF rfile.res = FileSystem.done THEN
FileSystem.Lookup(sfile,destPath,bufferSize,TRUE);
IF sfile.res = FileSystem.done THEN
REPEAT
FileSystem.ReadBytes(rfile,Buffer,bufferSize,rActual);
FileSystem.WriteBytes(sfile,Buffer,rActual,sActual);
UNTIL rfile.eof;
END;
FileSystem.Close(sfile);
srcLock:=Lock(ADR(srcPath),accessRead);
IF srcLock # NIL THEN
IF Examine(srcLock,cIPtr) THEN
MakePath(dest,"",destPath);
destLock:=Lock(ADR(destPath),accessRead);
IF destLock # NIL THEN
dLock:=DupLock(destLock); UnLock(destLock);
olddestLock:=CurrentDir(dLock); name[Length(name)-1]:=00C;
res:=SetOneDate(name,cIPtr^.date,LONGINT(dLock));
dLock:=CurrentDir(olddestLock);
IF dLock # NIL THEN UnLock(dLock); END;
ELSE
res:=FALSE;
END;
ELSE
res:=FALSE;
END;
UnLock(srcLock);
ELSE
res:=FALSE;
END;
ELSE
res:=FALSE;
END;
FileSystem.Close(rfile);
RETURN res;
END XCopySingleFile;
PROCEDURE XCopy(src,dest : ARRAY OF CHAR; type : XType): BOOLEAN;
VAR srcLock,
destLock : FileLockPtr;
bool : BOOLEAN;
name : ARRAY [0..31] OF CHAR;
path : ARRAY [0..255] OF CHAR;
BEGIN
IF AllocEntry(Buffer,bufferSize) THEN
IF type # single THEN
srcLock:=Lock(ADR(src),accessRead);
IF srcLock = NIL THEN RETURN FALSE END; destLock:=NIL;
src[Length(src)-1]:=00C; FilterLastDir(src,name);
MakePath(dest,name,path); path[Length(path)-1]:=00C;
destLock:=CreateDir(ADR(path));
IF destLock = NIL THEN
destLock:=Lock(ADR(path),accessRead);
IF destLock = NIL THEN RETURN FALSE END;
END;
bool:=TRUE;
IF XCopySubDirectories(srcLock,destLock,type) THEN
bool:=FALSE;
END;
UnLock(srcLock); UnLock(destLock);
ELSE
bool:=XCopySingleFile(src,dest);
END;
DeallocEntry(Buffer,bufferSize);
END;
RETURN bool;
END XCopy;
BEGIN
IF NOT AllocEntry(cIPtr,SIZE(FileInfoBlock)) THEN Terminate END;
END XCopy.